package com.bjpowernode.p2p.web;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.bjpowernode.common.constant.Constants;
import com.bjpowernode.common.util.CodeMessageRandom;
import com.bjpowernode.common.util.HttpClientUtils;
import com.bjpowernode.common.util.ResultMap;
import com.bjpowernode.p2p.model.user.FinanceAccount;
import com.bjpowernode.p2p.model.user.User;
import com.bjpowernode.p2p.service.FinanceAccountService;
import com.bjpowernode.p2p.service.RedisService;
import com.bjpowernode.p2p.service.UserService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * ClassName:UserController
 * Package:com.bjpowernode.p2p.web
 * Description: 处理用户类的请求：注册功能，登录功能
 *
 * @date:2021/7/18 7:07
 * @author:动力节点
 */
@Controller
public class UserController {

    @Reference(interfaceClass = UserService.class,check = false,version = "1.0-SNAPSHOT",timeout = 15000)
        private UserService userService;

    @Reference(interfaceClass = RedisService.class,check = false,version = "1.0-SNAPSHOT",timeout = 15000)
        private RedisService redisService;

    @Reference(interfaceClass = FinanceAccountService.class,check = false,version = "1.0-SNAPSHOT",timeout = 15000)
        private FinanceAccountService  financeAccountService;

    @RequestMapping("/loan/page/register")
    public String toRegistry(){
        return "register";
    }


    /**
     * 验证 手机号是否注册
     * @param phone
     * @return
     */

    @RequestMapping("/user/checkPhone")
    @ResponseBody
    public Map queryPhone(String phone){

        Map<String ,Object> map = new HashMap<>();

        User user = userService.queryPhone(phone);

        if(!ObjectUtils.allNotNull(user)){
            return  ResultMap.success();
        }else{
           return ResultMap.error("手机号："+phone+"已经被注册");
        }


    }

     // 生成验证码：发送验证码
    @RequestMapping("/checkCode")
    @ResponseBody
    public Map getCodeMessage(String phone) throws Exception {
        /*进行验证码校验 */
        //1. 获取 我们后台生成的 随机六位数 验证码：
        String codeMessage = CodeMessageRandom.getRandomCodeMessage();
        //如下都是根据第三方接口要求的键值对进行传值
        //2. 连接短信接口，进行验证码发送：【多数为固定写法】
        Map<String,String> paramMap =new HashMap<String,String>();
        //将 开发者秘钥 存进该集合：key:appkey;值，在接口的测试处会展示
        paramMap.put("appkey","您要输入的开发者秘钥");//在第三方接口官网可获取秘钥
        // 将需要发送的 验证码的手机号传入:key=mobile
        paramMap.put("mobile",phone);//就是前端传来的phone
        //将发送内容存入该集合：
        paramMap.put("content","【凯信通】您的验证码是："+codeMessage+",有效时间：5分钟。");
        //调用短信接口，传入参数，返回json+xml格式的结果集；接口在第三方接口官网可以获取
      // String resultJson = HttpClientUtils.doGet("https://way.jd.com/kaixintong/kaixintong", paramMap);
        String resultJson = "{\n" +
                "\"code\": \"10000\",\n" +
                "\"charge\": false,\n" +
                "\"remain\": 0,\n" +
                "\"msg\": \"查询成功\",\n" +
                "\"result\": \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\" ?><returnsms>\\n <returnstatus>Success</returnstatus>\\n <message>ok</message>\\n <remainpoint>-7509443</remainpoint>\\n <taskID>187288073</taskID>\\n <successCounts>1</successCounts></returnsms>\",\n" +
                "\"requestId\": \"5156263d4f014324a77f40ed174a8b8f\"\n" +
                "}";
                //遍历结果集
        JSONObject json = JSONObject.parseObject(resultJson);
        //获取code,如果code为10000，则表明请求成功
        String code = json.getString("code");
        if(!StringUtils.equals(code,"10000")){//code不等于10000；则表明求情错误
         return    ResultMap.error("验证码请求失败：code不等于10000");//ResultMap是自己封装的一个结果类
        }
        //获取查询结果
        String result = json.getString("result");
        //解析查询结果
        Document document = DocumentHelper.parseText(result);
        Node node = document.selectSingleNode("/returnsms/returnstatus[1]");
        String returnstatus = node.getText();
        if (!StringUtils.equals(returnstatus,"Success")) {
            ResultMap.error("请求验证码失败：returnStatus的值不是success");
        }
        //将验证码 存在redis 中， 并且 设置失效时间
        // 存在 redis中后， 当点击注册 后，前端传来的验证码
        // 要是 与 我们生成的 验证码 并存在 redis 一致，才能继续注册
        redisService.addCodeMessage(phone,codeMessage);//key为用户手机号，value为当时生成的验证码

        return ResultMap.success("验证码是："+codeMessage);
    }


    /**
     * 注册用户
     * @param request
     * @param phone
     * @param loginPassword
     * @return
     * @throws Exception
     */
    @RequestMapping("/registry/addUser")
    @ResponseBody
    public Map addUser(HttpServletRequest request,
                       @RequestParam(value = "codeMessage",required = true) String codeMessage,
                       @RequestParam(value = "phone",required = true) String phone,
                       @RequestParam(value = "loginPassword",required = true) String loginPassword) throws Exception {

      //进行 验证码 验证 ： 获取的 验证码 要与 redis 存储 的验证码 一致才能继续
     String redisCode = redisService.getCodeMessage(phone);
      if(!StringUtils.equals(redisCode,codeMessage)){//如果存在redis的验证码 与 前端传来的 验证码 不一致
          return ResultMap.error("验证码有误！");
      }
          //因为 注册成功后，我们需要返回该对象，将该对象存入session中，然后实现注册成功直接登录功能
        //同时，在注册的的时候，我们同步给该账户创建一个金融账户
        User user = userService.addUser(phone,loginPassword);

        if(!ObjectUtils.allNotNull(user)){
            return ResultMap.error("注册失败");
        }else {
            //根据用户id查询金融账户
           FinanceAccount financeAccount = financeAccountService.queryFinanceAccount(user.getId());
           user.setFinanceAccount(financeAccount);
            //将对象存入session中，
            request.getSession().setAttribute(Constants.USER,user);
            return ResultMap.success();

        }

    }

    /*实名认证：页面跳转*/
    @RequestMapping("/realName")
    public String toRealName(){
        return "realName";
    }

    /**
     * 请求第三方接口处理 身份认证！
     * @return
     */
    @RequestMapping("/realName/conform")
    @ResponseBody
    public Map realNameCheck(HttpServletRequest request,
                             @RequestParam(value = "messageCode",required = true)String messageCode,
                             @RequestParam(value = "phone",required = true)String phone,
                             @RequestParam(value = "realName",required = true) String realName,
                             @RequestParam(value = "idCard",required = true) String idCard) throws Exception {

        //判断验证码是否正确
        String reidsCodeMessage = redisService.getCodeMessage(phone);
        if (!StringUtils.equals(reidsCodeMessage, messageCode)) {
            return ResultMap.error("验证码过期！请重新获取！");
        }

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appkey", "ee178f6c87576bc19c8dd98a5f8ee58e");
        paramMap.put("realName", realName);
        paramMap.put("cardNo", idCard);
        //String jsonString = HttpClientUtils.doPost("https://way.jd.com/hl/checkidcard", paramMap);
        String jsonString = "{\n" +
                "\"code\": \"10000\",\n" +
                "\"charge\": false,\n" +
                "\"remain\": 1305,\n" +
                "\"msg\": \"查询成功\",\n" +
                "\"result\": {\n" +
                "    \"error_code\": 0,\n" +
                "    \"reason\": \"成功\",\n" +
                "    \"result\": {\n" +
                "        \"realname\": \"乐天磊\",\n" +
                "        \"idcard\": \"350721197702134399\",\n" +
                "        \"isok\": true\n" +
                "    }\n" +
                "    }\n" +
                "}";
               // 把json格式的字符串转成json对象
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        // 从json对象中获取相关信息
        String code = jsonObject.getString("code");
        if (!StringUtils.equals(code, "10000")) {
            // 通信异常
            return ResultMap.error("通信异常");
        }
        // 获取isok判断是否返回成功
        Boolean isOk = jsonObject.getJSONObject("result").getJSONObject("result").getBoolean("isok");
        if (!isOk) {
            return ResultMap.error("姓名与身份证匹配失败");
        }
        //通过验证后：将更新user数据库：因为我们在注册的时候已经将user存在session中，
        // 所以只需获取session中的user进行修改，也能实现业务后期实名认证
        User user = (User) request.getSession().getAttribute(Constants.USER);
        user.setIdCard(idCard);
        user.setName(realName);
        int i = userService.modifyUser(user);
        if (i < 0) {
            return ResultMap.error("实名认证失败！");
        } else {
            return ResultMap.success();
        }
    }

    //页面跳转:跳转到个人中心；页面不能跳转：
    @RequestMapping("/loan/myCenter")
    public String toMyCenter(HttpServletRequest request){
        //获取session；；如果有值，才能进入到个人中心
        User user = (User) request.getSession().getAttribute(Constants.USER);
        if(ObjectUtils.allNotNull(user)){
            //说明session中有值：有值则进入个人中心
            return "myCenter";
        }else {
            //跳转到登录页面：
            return "/loan/page/login";
        }


    }


    /**
     * 登录功能
     * @return
     */
    @RequestMapping("/loan/page/login")
    public String toLogin(){
        return "login";
    }

    /**
     * 登录验证
     * @param phone
     * @param loginPassword
     * @param messageCode
     * @return
     */
    @RequestMapping("/loginCheck")
    @ResponseBody
    public Map LoginCheck(HttpServletRequest request,
                          @RequestParam(value = "phone",required = true) String phone,
                          @RequestParam(value = "loginPassword",required = true) String loginPassword,
                          @RequestParam(value = "messageCode",required = true) String messageCode){

       // 对验证码进行验证
        String redisMessageCode = redisService.getCodeMessage(phone);
        if(!StringUtils.equals(redisMessageCode,messageCode)){//验证码不相等
            return ResultMap.error("验证码不正确，请重新获取！");
        }
        //对账户进行验证：手机号 and 密码
        User user = userService.queryLoginCheck(phone,loginPassword);
        if(ObjectUtils.allNotNull(user)){
            //将user存到session中；
            request.getSession().setAttribute(Constants.USER,user);
            return ResultMap.success();
        }else{
            return ResultMap.error("账户和密码错误，请重新登录！");
        }
    }

    /**
     * 退出功能
     * @return
     */
    @RequestMapping("/loan/logout")
    public String loginOut(HttpServletRequest request){
       //删除session中的user对象：
        request.getSession().removeAttribute(Constants.USER);
        //退出不能用跳转，只能用重定向：/表示上下文根，即/dev
        return "redirect:/index";
    }
}
